<?php
/**
 * Created by PhpStorm.
 * User: 王松
 * Time: 2017/7/30 17:23
 */

namespace App\Project\Reserve;

use App\Project\Reserve\Behaviours\Launch;
use App\Project\Reserve\Behaviours\Look;
use App\Project\Reserve\Behaviours\Schedule;
use App\Project\Reserve\Exceptions\ReservationForbiddenException;
use App\Project\Reserve\Statistics\Situation;
use App\Project\Reserve\Statistics\Visit;
use App\User;
use Illuminate\Http\Request;

class Reserve
{
    /**
     * @var User
     */
    protected $user;

    /**
     * @var \Silber\Bouncer\Bouncer
     */
    protected $bouncer;

    /**
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * Reserve constructor.
     * @param \App\User $user
     */
    public function __construct(User $user)
    {
        $this->setUser($user);
    }

    /**
     * 发起预约
     * @return \App\Project\Reserve\Behaviours\Launch
     */
    public function launch()
    {
        return new Launch($this->user);
    }

    public function launchTo($patient, array $attributes)
    {
        return $this->launch()->to($patient, $attributes);
    }

    /**
     * @param \App\Models\Reservation\Reservation|null $reservation
     * @return \App\Project\Reserve\Behaviours\Look
     */
    public function look($reservation = null)
    {
        return new Look($this->user, $reservation);
    }

    /**
     * @param $time
     * @return \App\Project\Reserve\Statistics\Situation
     */
    public function situation($time)
    {
        return new Situation($this->user, $time);
    }

    public function visit($week, callable $callback = null)
    {
        $visit = new Visit($this->user);

        if ($callback) {
            $callback($visit);
        }

        return $visit->call($week);
    }

    public function schedule()
    {
        return new Schedule($this->user);
    }

    /**
     * @param      $user
     * @param null $times
     * @return \Illuminate\Support\Collection|static
     */
    public function plan($user, $times = null)
    {
        return $this->schedule()->setUser($user)->plan($times);
    }

    /**
     * @param \App\User $user
     * @return array
     */
    public function plans(User $user)
    {
        return $this->schedule()->setUser($user)->plans();
    }

    /**
     * @param $user
     * @param $time
     * @return \App\Project\Reserve\Behaviours\Schedule|\Illuminate\Support\Collection
     */
    public function planOfMonth($user, $time)
    {
        return $this->schedule()->setUser($user)->planOfMonth($time);
    }



    /**
     * @param \App\User $user
     * @return $this
     * @throws \App\Project\Reserve\Exceptions\ReservationForbiddenException
     */
    public function setUser(User $user)
    {
        if ($user->canReservation()) {
            $this->user = $user;

            return $this;
        }

        throw new ReservationForbiddenException();
    }

    /**
     * @param \Illuminate\Http\Request $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getUser()
    {
        return $this->user;
    }
}